home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / modex32w.zip / FILLPAT.ASM < prev    next >
Assembly Source File  |  1995-02-21  |  9KB  |  190 lines

  1.         .386
  2.         locals
  3.         include w.inc
  4.  
  5. ; Mode X (320x240, 256 colors) rectangle 4x4 pattern fill routine.
  6. ; Upper left corner of pattern is always aligned to a multiple-of-4
  7. ; row and column. Works on all VGAs. Uses approach of copying the
  8. ; pattern to off-screen display memory, then loading the latches with
  9. ; the pattern for each scan line and filling each scan line four
  10. ; pixels at a time. Fills up to but not including the column at EndX
  11. ; and the row at EndY. No clipping is performed. All ASM code tested
  12. ; with TASM 2. C near-callable as:
  13. ;    void FillPatternedX(int StartX, int StartY, int EndX, int EndY,
  14. ;       unsigned int PageBase, char* Pattern);
  15.  
  16. SC_INDEX equ    03c4h   ;Sequence Controller Index register port
  17. MAP_MASK equ    02h     ;index in SC of Map Mask register
  18. GC_INDEX equ    03ceh   ;Graphics Controller Index register port
  19. BIT_MASK equ    08h     ;index in GC of Bit Mask register
  20. PATTERN_BUFFER equ 0fffch ;offset in screen memory of the buffer used
  21.                         ; to store each pattern during drawing
  22. parms   struc
  23.         dd      2 dup (?) ;pushed BP and return address
  24. StartX  dd      ?       ;X coordinate of upper left corner of rect
  25. StartY  dd      ?       ;Y coordinate of upper left corner of rect
  26. EndX    dd      ?       ;X coordinate of lower right corner of rect
  27.                         ; (the row at EndX is not filled)
  28. EndY    dd      ?       ;Y coordinate of lower right corner of rect
  29.                         ; (the column at EndY is not filled)
  30. PageBase dd     ?       ;base offset in display memory of page in
  31.                         ; which to fill rectangle
  32. Pattern dd      ?       ;4x4 pattern with which to fill rectangle
  33. parms   ends
  34.  
  35. NextScanOffset equ -4   ;local storage for distance from end of one
  36.                         ; scan line to start of next
  37. RectAddrWidth equ -8    ;local storage for address width of rectangle
  38. Height   equ     -12    ;local storage for height of rectangle
  39. WrapCheck equ   -16     ;local for pattern wrap
  40. STACK_FRAME_SIZE equ 16
  41.  
  42.         @dseg
  43.  
  44.         extrn   SCREEN_SEG:dword
  45.         extrn   SCREEN_WIDTH:dword
  46.         extrn   LeftClipPlaneMask:byte
  47.         extrn   RightClipPlaneMask:byte
  48.  
  49.         ends
  50.  
  51.         @cseg
  52.  
  53.         public  _FillPatternX
  54. _FillPatternX proc    near
  55.         push    ebp      ;preserve caller's stack frame
  56.         mov     ebp,esp   ;point to local stack frame
  57.         sub     esp,STACK_FRAME_SIZE ;allocate space for local vars
  58.         push    esi      ;preserve caller's register variables
  59.         push    edi
  60.         push    ebx
  61.  
  62.         cld
  63.                                 ;copy pattern to display memory buffer
  64.         mov     esi,[ebp+Pattern] ;point to pattern to fill with
  65.         mov     edi,PATTERN_BUFFER ;point EDI to pattern buffer
  66.         add     edi,[SCREEN_SEG]   ;    on screen
  67.         mov     dx,SC_INDEX     ;point Sequence Controller Index to
  68.         mov     al,MAP_MASK     ; Map Mask
  69.         out     dx,al
  70.         inc     dx              ;point to SC Data register
  71.         mov     ecx,4            ;4 pixel quadruplets in pattern
  72. DownloadPatternLoop:
  73.         mov     al,1            ;
  74.         out     dx,al           ;select plane 0 for writes
  75.         movsb                   ;copy over next plane 0 pattern pixel
  76.         dec     edi             ;stay at same address for next plane
  77.         mov     al,2            ;
  78.         out     dx,al           ;select plane 1 for writes
  79.         movsb                   ;copy over next plane 1 pattern pixel
  80.         dec     edi             ;stay at same address for next plane
  81.         mov     al,4            ;
  82.         out     dx,al           ;select plane 2 for writes
  83.         movsb                   ;copy over next plane 2 pattern pixel
  84.         dec     edi             ;stay at same address for next plane
  85.         mov     al,8            ;
  86.         out     dx,al           ;select plane 3 for writes
  87.         movsb                   ;copy over next plane 3 pattern pixel
  88.                                 ; and advance address
  89.         loop    DownloadPatternLoop
  90.  
  91.         mov     dx,GC_INDEX     ;set the bit mask to select all bits
  92.         mov     ax,00000h+BIT_MASK ; from the latches and none from
  93.         out     dx,ax           ; the CPU, so that we can write the
  94.                                 ; latch contents directly to memory
  95.         mov     eax,[ebp+StartY]  ;top rectangle scan line
  96.         mov     esi,eax
  97.         and     esi,011b         ;top rect scan line modulo 4
  98.         add     esi,PATTERN_BUFFER ;point to pattern scan line that
  99.                                 ; maps to top line of rect to draw
  100.         mov     edx,[SCREEN_WIDTH]
  101.         mul     edx      ;offset in page of top rectangle scan line
  102.         mov     edi,[ebp+StartX]
  103.         mov     ebx,edi
  104.         shr     edi,2    ;X/4 = offset of first rectangle pixel in scan line
  105.         add     edi,eax   ;offset of first rectangle pixel in page
  106.         add     edi,[ebp+PageBase] ;offset of first rectangle pixel in
  107.                         ; display memory
  108.         and     ebx,0003h                 ;look up left edge plane mask
  109.         mov     ah,LeftClipPlaneMask[ebx] ; to clip
  110.         mov     ebx,[ebp+EndX]
  111.         and     ebx,0003h                  ;look up right edge plane
  112.         mov     al,RightClipPlaneMask[ebx] ; mask to clip
  113.         mov     ebx,eax                   ;put the masks in BX
  114.         
  115.         mov     ecx,[ebp+EndX]    ;calculate # of addresses across rect
  116.         mov     eax,[ebp+StartX]
  117.         cmp     ecx,eax
  118.         jle     FillDone        ;skip if 0 or negative width
  119.         dec     ecx
  120.         and     eax,not 011b
  121.         sub     ecx,eax
  122.         shr     ecx,2    ;# of addresses across rectangle to fill - 1
  123.         jnz     MasksSet ;there's more than one pixel to draw
  124.         and     bh,bl   ;there's only one pixel, so combine the left
  125.                         ; and right edge clip masks
  126. MasksSet:
  127.         mov     eax,[ebp+EndY]
  128.         sub     eax,[ebp+StartY]  ;EAX = height of rectangle
  129.         jle     FillDone        ;skip if 0 or negative height
  130.         mov     [ebp+Height],eax
  131.         mov     eax,SCREEN_WIDTH
  132.         sub     eax,ecx   ;distance from end of one scan line to start
  133.         dec     eax      ; of next
  134.         mov     [ebp+NextScanOffset],eax
  135.         mov     [ebp+RectAddrWidth],ecx ;remember width in addresses - 1
  136.         mov     dx,SC_INDEX+1 ;point to Sequence Controller Data reg
  137.                                 ; (SC Index still points to Map Mask)
  138.         mov     ecx, [SCREEN_SEG]
  139.         add     edi, ecx
  140.         add     esi, ecx
  141.         mov     [ebp+WrapCheck], esi
  142.         add     dword ptr [ebp+WrapCheck], 4
  143. FillRowsLoop:
  144.         mov     ecx,[ebp+RectAddrWidth] ;width across - 1
  145.         mov     al,[esi] ;read display memory to latch this scan
  146.                          ; line's pattern
  147.         inc     esi      ;point to the next pattern scan line, wrapping
  148.  
  149.         cmp     esi, [ebp+WrapCheck]
  150.         jl      NoWrap   ; back to the start of the pattern if
  151.         sub     esi,4    ; we've run off the end
  152. NoWrap:
  153.         mov     al,bh   ;put left-edge clip mask in AL
  154.         out     dx,al   ;set the left-edge plane (clip) mask
  155.         stosb           ;draw the left edge (pixels come from latches;
  156.                         ; value written by CPU doesn't matter)
  157.         dec     ecx      ;count off left edge address
  158.         js      FillLoopBottom ;that's the only address
  159.         jz      DoRightEdge ;there are only two addresses
  160.         mov     al,00fh ;middle addresses are drawn 4 pixels at a pop
  161.         out     dx,al   ;set the middle pixel mask to no clip
  162.         rep     stosb   ;draw the middle addresses four pixels apiece
  163.                         ; (from latches; value written doesn't matter)
  164. DoRightEdge:
  165.         mov     al,bl   ;put right-edge clip mask in AL
  166.         out     dx,al   ;set the right-edge plane (clip) mask
  167.         stosb           ;draw the right edge (from latches; value
  168.                         ; written doesn't matter)
  169. FillLoopBottom:
  170.         add     edi,[ebp+NextScanOffset] ;point to the start of the next scan
  171.                                         ; line of the rectangle
  172.         dec     dword ptr [ebp+Height] ;count down scan lines
  173.         jnz     FillRowsLoop
  174. FillDone:
  175.         mov     dx,GC_INDEX+1 ;restore the bit mask to its default,
  176.         mov     al,0ffh       ; which selects all bits from the CPU
  177.         out     dx,al         ; and none from the latches (the GC
  178.                               ; Index still points to Bit Mask)
  179.         pop     ebx
  180.         pop     edi      ;restore caller's register variables
  181.         pop     esi
  182.         mov     esp,ebp   ;discard storage for local variables
  183.         pop     ebp      ;restore caller's stack frame
  184.         ret
  185. _FillPatternX endp
  186.         ends
  187.         end
  188.  
  189.  
  190.